/*! ******************************************************************************
*
* Pentaho Data Integration
*
* Copyright (C) 2002-2017 by Hitachi Vantara : http://www.pentaho.com
*
*******************************************************************************
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
*    http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************/

package org.pentaho.di.ui.trans.steps.shentong.oss;

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.FocusListener;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.ShellAdapter;
import org.eclipse.swt.events.ShellEvent;
import org.eclipse.swt.graphics.Cursor;
import org.eclipse.swt.layout.FormAttachment;
import org.eclipse.swt.layout.FormData;
import org.eclipse.swt.layout.FormLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import org.pentaho.di.core.Const;
import org.pentaho.di.i18n.BaseMessages;
import org.pentaho.di.trans.TransMeta;
import org.pentaho.di.trans.step.BaseStepMeta;
import org.pentaho.di.trans.step.StepDialogInterface;
import org.pentaho.di.ui.core.widget.ComboVar;
import org.pentaho.di.ui.core.widget.TextVar;
import org.pentaho.di.ui.trans.step.BaseStepDialog;

/**
 * This class is part of the demo step plug-in implementation. It demonstrates
 * the basics of developing a plug-in step for PDI.
 * 
 * The demo step adds a new string field to the row stream and sets its value to
 * "Hello World!". The user may select the name of the new field.
 * 
 * This class is the implementation of StepDialogInterface. Classes implementing
 * this interface need to:
 * 
 * - build and open a SWT dialog displaying the step's settings (stored in the
 * step's meta object) - write back any changes the user makes to the step's
 * meta object - report whether the user changed any settings when confirming
 * the dialog
 * 
 */
public class ShenTongOssStepDialog extends BaseStepDialog implements StepDialogInterface {

	/**
	 * The PKG member is used when looking up internationalized strings. The
	 * properties file with localized keys is expected to reside in {the package of
	 * the class specified}/messages/messages_{locale}.properties
	 */
	private static Class<?> PKG = ShenTongOssStepMeta.class; // for i18n purposes

	// this is the object the stores the step's settings
	// the dialog reads the settings from it when opening
	// the dialog writes the settings to it when confirmed
	private ShenTongOssStepMeta meta;

	private Label wlUploadHost;

	private FormData fdlUploadHost;

	private TextVar wUploadHost;

	private FormData fdUploadHost;

	private Label wlUser;

	private FormData fdlUser;

	private TextVar wUser;

	private FormData fdUser;

	private Label wlPassword;

	private FormData fdlPassword;

	private TextVar wPassword;

	private FormData fdPassword;

	private Label wlbinaryField;

	private FormData fdlbinaryField;

	private ComboVar wbinaryField;

	private FormData fdbinaryField;

	private Label wldownloadField;

	private FormData fdldownloadField;

	private TextVar wdownloadField;

	private FormData fddownloadField;

	private Label wlBucket;

	private FormData fdlBucket;

	private TextVar wBucket;

	private FormData fdBucket;

	private Label wlfileNameField;

	private FormData fdlfileNameField;

	private ComboVar wfileNameField;

	private FormData fdfileNameField;

	/**
	 * The constructor should simply invoke super() and save the incoming meta
	 * object to a local variable, so it can conveniently read and write settings
	 * from/to it.
	 * 
	 * @param parent    the SWT shell to open the dialog in
	 * @param in        the meta object holding the step's settings
	 * @param transMeta transformation description
	 * @param sname     the step name
	 */
	public ShenTongOssStepDialog(Shell parent, Object in, TransMeta transMeta, String sname) {
		super(parent, (BaseStepMeta) in, transMeta, sname);
		meta = (ShenTongOssStepMeta) in;
	}

	/**
	 * This method is called by Spoon when the user opens the settings dialog of the
	 * step. It should open the dialog and return only once the dialog has been
	 * closed by the user.
	 * 
	 * If the user confirms the dialog, the meta object (passed in the constructor)
	 * must be updated to reflect the new step settings. The changed flag of the
	 * meta object must reflect whether the step configuration was changed by the
	 * dialog.
	 * 
	 * If the user cancels the dialog, the meta object must not be updated, and its
	 * changed flag must remain unaltered.
	 * 
	 * The open() method must return the name of the step after the user has
	 * confirmed the dialog, or null if the user cancelled the dialog.
	 */
	public String open() {
		Shell parent = getParent();
		Display display = parent.getDisplay();

		shell = new Shell(parent, SWT.DIALOG_TRIM | SWT.RESIZE | SWT.MIN | SWT.MAX);
		props.setLook(shell);
		setShellImage(shell, meta);

		// Save the value of the changed flag on the meta object. If the user cancels
		// the dialog, it will be restored to this saved value.
		// The "changed" variable is inherited from BaseStepDialog
		changed = meta.hasChanged();

		// ModifyListener应用所有的组件，当组件值更新时自动更新meta信息
		ModifyListener lsMod = new ModifyListener() {
			public void modifyText(ModifyEvent e) {
				meta.setChanged();
			}
		};

		// 步骤配置项表单
		FormLayout formLayout = new FormLayout();
		formLayout.marginWidth = Const.FORM_MARGIN;
		formLayout.marginHeight = Const.FORM_MARGIN;
		shell.setLayout(formLayout);
		shell.setText(BaseMessages.getString(PKG, "ShenTongOss.Shell.Title"));
		int middle = props.getMiddlePct();
		int margin = Const.MARGIN;

		// 步骤名称
		wlStepname = new Label(shell, SWT.RIGHT);
		wlStepname.setText(BaseMessages.getString(PKG, "System.Label.StepName"));
		props.setLook(wlStepname);
		fdlStepname = new FormData();
		fdlStepname.left = new FormAttachment(0, 0);
		fdlStepname.right = new FormAttachment(middle, -margin);
		fdlStepname.top = new FormAttachment(0, margin);
		wlStepname.setLayoutData(fdlStepname);

		wStepname = new Text(shell, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
		wStepname.setText(stepname);
		props.setLook(wStepname);
		wStepname.addModifyListener(lsMod);
		fdStepname = new FormData();
		fdStepname.left = new FormAttachment(middle, 0);
		fdStepname.top = new FormAttachment(0, margin);
		fdStepname.right = new FormAttachment(100, 0);
		wStepname.setLayoutData(fdStepname);

		// OSS上传地址
		wlUploadHost = new Label(shell, SWT.RIGHT);
		wlUploadHost.setText(BaseMessages.getString(PKG, "ShenTongOss.UploadURL.Label"));
		props.setLook(wlUploadHost);
		fdlUploadHost = new FormData();
		fdlUploadHost.left = new FormAttachment(0, 0);
		fdlUploadHost.right = new FormAttachment(middle, -margin);
		fdlUploadHost.top = new FormAttachment(wStepname, margin);
		wlUploadHost.setLayoutData(fdlUploadHost);
		wUploadHost = new TextVar(transMeta, shell, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
		wUploadHost.setText("");
		props.setLook(wUploadHost);
		wUploadHost.addModifyListener(lsMod);
		fdUploadHost = new FormData();
		fdUploadHost.left = new FormAttachment(middle, 0);
		fdUploadHost.top = new FormAttachment(wStepname, margin);
		fdUploadHost.right = new FormAttachment(100, 0);
		wUploadHost.setLayoutData(fdUploadHost);

		// OSS登录用户名
		wlUser = new Label(shell, SWT.RIGHT);
		wlUser.setText(BaseMessages.getString(PKG, "ShenTongOss.User.Label"));
		props.setLook(wlUser);
		fdlUser = new FormData();
		fdlUser.left = new FormAttachment(0, 0);
		fdlUser.right = new FormAttachment(middle, -margin);
		fdlUser.top = new FormAttachment(wUploadHost, margin);
		wlUser.setLayoutData(fdlUser);
		wUser = new TextVar(transMeta, shell, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
		wUser.setText("");
		props.setLook(wUser);
		wUser.addModifyListener(lsMod);
		fdUser = new FormData();
		fdUser.left = new FormAttachment(middle, 0);
		fdUser.top = new FormAttachment(wUploadHost, margin);
		fdUser.right = new FormAttachment(100, 0);
		wUser.setLayoutData(fdUser);

		// OSS登录密码
		wlPassword = new Label(shell, SWT.RIGHT);
		wlPassword.setText(BaseMessages.getString(PKG, "ShenTongOss.Password.Label"));
		props.setLook(wlPassword);
		fdlPassword = new FormData();
		fdlPassword.left = new FormAttachment(0, 0);
		fdlPassword.right = new FormAttachment(middle, -margin);
		fdlPassword.top = new FormAttachment(wUser, margin);
		wlPassword.setLayoutData(fdlPassword);
		wPassword = new TextVar(transMeta, shell, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
		wPassword.setText("");
		props.setLook(wPassword);
		wPassword.addModifyListener(lsMod);
		fdPassword = new FormData();
		fdPassword.left = new FormAttachment(middle, 0);
		fdPassword.top = new FormAttachment(wUser, margin);
		fdPassword.right = new FormAttachment(100, 0);
		wPassword.setLayoutData(fdPassword);
		
		// OSS bucket名称
		wlBucket = new Label(shell, SWT.RIGHT);
		wlBucket.setText(BaseMessages.getString(PKG, "ShenTongOss.Bucket.Label"));
		props.setLook(wlBucket);
		fdlBucket = new FormData();
		fdlBucket.left = new FormAttachment(0, 0);
		fdlBucket.right = new FormAttachment(middle, -margin);
		fdlBucket.top = new FormAttachment(wPassword, margin);
		wlBucket.setLayoutData(fdlBucket);
		wBucket = new TextVar(transMeta, shell, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
		wBucket.setText("");
		props.setLook(wBucket);
		wBucket.addModifyListener(lsMod);
		fdBucket = new FormData();
		fdBucket.left = new FormAttachment(middle, 0);
		fdBucket.top = new FormAttachment(wPassword, margin);
		fdBucket.right = new FormAttachment(100, 0);
		wBucket.setLayoutData(fdBucket);

		// 二进制字段
		wlbinaryField = new Label(shell, SWT.RIGHT);
		wlbinaryField.setText(BaseMessages.getString(PKG, "ShenTongOss.BinaryField.Label"));
		props.setLook(wlbinaryField);
		fdlbinaryField = new FormData();
		fdlbinaryField.left = new FormAttachment(0, 0);
		fdlbinaryField.right = new FormAttachment(middle, -margin);
		fdlbinaryField.top = new FormAttachment(wBucket, margin);
		wlbinaryField.setLayoutData(fdlbinaryField);

		wbinaryField = new ComboVar(transMeta, shell, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
		wbinaryField.setToolTipText(BaseMessages.getString(PKG, "ShenTongOss.BinaryField.Tooltip"));
		props.setLook(wbinaryField);
		wbinaryField.addModifyListener(lsMod);
		fdbinaryField = new FormData();
		fdbinaryField.left = new FormAttachment(middle, 0);
		fdbinaryField.top = new FormAttachment(wBucket, margin);
		fdbinaryField.right = new FormAttachment(100, 0);
		wbinaryField.setLayoutData(fdbinaryField);
		wbinaryField.addFocusListener(new FocusListener() {
			public void focusLost(org.eclipse.swt.events.FocusEvent e) {
			}

			public void focusGained(org.eclipse.swt.events.FocusEvent e) {
				Cursor busy = new Cursor(shell.getDisplay(), SWT.CURSOR_WAIT);
				shell.setCursor(busy);
				BaseStepDialog.getFieldsFromPrevious(wbinaryField, transMeta, stepMeta);
				shell.setCursor(null);
				busy.dispose();
			}
		});
		
		// 文件名字段
		wlfileNameField = new Label(shell, SWT.RIGHT);
		wlfileNameField.setText(BaseMessages.getString(PKG, "ShenTongOss.FileNameField.Label"));
		props.setLook(wlfileNameField);
		fdlfileNameField = new FormData();
		fdlfileNameField.left = new FormAttachment(0, 0);
		fdlfileNameField.right = new FormAttachment(middle, -margin);
		fdlfileNameField.top = new FormAttachment(wbinaryField, margin);
		wlfileNameField.setLayoutData(fdlfileNameField);

		wfileNameField = new ComboVar(transMeta, shell, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
		wfileNameField.setToolTipText(BaseMessages.getString(PKG, "ShenTongOss.FileNameField.Tooltip"));
		props.setLook(wfileNameField);
		wfileNameField.addModifyListener(lsMod);
		fdfileNameField = new FormData();
		fdfileNameField.left = new FormAttachment(middle, 0);
		fdfileNameField.top = new FormAttachment(wbinaryField, margin);
		fdfileNameField.right = new FormAttachment(100, 0);
		wfileNameField.setLayoutData(fdfileNameField);
		wfileNameField.addFocusListener(new FocusListener() {
			public void focusLost(org.eclipse.swt.events.FocusEvent e) {
			}

			public void focusGained(org.eclipse.swt.events.FocusEvent e) {
				Cursor busy = new Cursor(shell.getDisplay(), SWT.CURSOR_WAIT);
				shell.setCursor(busy);
				BaseStepDialog.getFieldsFromPrevious(wfileNameField, transMeta, stepMeta);
				shell.setCursor(null);
				busy.dispose();
			}
		});
		
		// 下载地址字段
		wldownloadField = new Label(shell, SWT.RIGHT);
		wldownloadField.setText(BaseMessages.getString(PKG, "ShenTongOss.Download.Label"));
		wldownloadField.setToolTipText(BaseMessages.getString(PKG, "ShenTongOss.Download.Tooltip"));
		props.setLook(wldownloadField);
		fdldownloadField = new FormData();
		fdldownloadField.left = new FormAttachment(0, 0);
		fdldownloadField.right = new FormAttachment(middle, -margin);
		fdldownloadField.top = new FormAttachment(wfileNameField, margin);
		wldownloadField.setLayoutData(fdldownloadField);
		wdownloadField = new TextVar(transMeta, shell, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
		wdownloadField.setText("");
		props.setLook(wdownloadField);
		wdownloadField.addModifyListener(lsMod);
		fddownloadField = new FormData();
		fddownloadField.left = new FormAttachment(middle, 0);
		fddownloadField.top = new FormAttachment(wfileNameField, margin);
		fddownloadField.right = new FormAttachment(100, 0);
		wdownloadField.setLayoutData(fddownloadField);
		
		// OK and cancel buttons
		wOK = new Button(shell, SWT.PUSH);
		wOK.setText(BaseMessages.getString(PKG, "System.Button.OK"));
		wCancel = new Button(shell, SWT.PUSH);
		wCancel.setText(BaseMessages.getString(PKG, "System.Button.Cancel"));
		setButtonPositions(new Button[] { wOK, wCancel }, margin, wldownloadField);

		// Add listeners for cancel and OK
		lsCancel = new Listener() {
			public void handleEvent(Event e) {
				cancel();
			}
		};
		lsOK = new Listener() {
			public void handleEvent(Event e) {
				ok();
			}
		};
		wCancel.addListener(SWT.Selection, lsCancel);
		wOK.addListener(SWT.Selection, lsOK);

		// default listener (for hitting "enter")
		lsDef = new SelectionAdapter() {
			public void widgetDefaultSelected(SelectionEvent e) {
				ok();
			}
		};
		wStepname.addSelectionListener(lsDef);
		wdownloadField.addSelectionListener(lsDef);

		// Detect X or ALT-F4 or something that kills this window and cancel the dialog
		// properly
		shell.addShellListener(new ShellAdapter() {
			public void shellClosed(ShellEvent e) {
				cancel();
			}
		});

		// Set/Restore the dialog size based on last position on screen
		// The setSize() method is inherited from BaseStepDialog
		setSize();

		// populate the dialog with the values from the meta object
		populateDialog();

		// restore the changed flag to original value, as the modify listeners fire
		// during dialog population
		meta.setChanged(changed);

		// open dialog and enter event loop
		shell.open();
		while (!shell.isDisposed()) {
			if (!display.readAndDispatch()) {
				display.sleep();
			}
		}

		// at this point the dialog has closed, so either ok() or cancel() have been
		// executed
		// The "stepname" variable is inherited from BaseStepDialog
		return stepname;
	}

	/**
	 * This helper method puts the step configuration stored in the meta object and
	 * puts it into the dialog controls.
	 */
	private void populateDialog() {
		wStepname.selectAll();
		wUploadHost.setText(meta.getUploadHost());
		wUser.setText(meta.getUser());
		wPassword.setText(meta.getPassword());
		wBucket.setText(meta.getBucket());
		wbinaryField.setText(meta.getBinaryField());
		wfileNameField.setText(meta.getFileNameField());
		wdownloadField.setText(meta.getDownloadField());
	}

	/**
	 * Called when the user cancels the dialog.
	 */
	private void cancel() {
		// The "stepname" variable will be the return value for the open() method.
		// Setting to null to indicate that dialog was cancelled.
		stepname = null;
		// Restoring original "changed" flag on the met aobject
		meta.setChanged(changed);
		// close the SWT dialog window
		dispose();
	}

	/**
	 * Called when the user confirms the dialog
	 */
	private void ok() {
		// The "stepname" variable will be the return value for the open() method.
		// Setting to step name from the dialog control
		stepname = wStepname.getText();
		// Setting the settings to the meta object
		
		meta.setUploadHost(wUploadHost.getText());
		meta.setUser(wUser.getText());
		meta.setPassword(wPassword.getText());
		meta.setBucket(wBucket.getText());
		meta.setBinaryField(wbinaryField.getText());
		meta.setFileNameField(wfileNameField.getText());
		meta.setDownloadField(wdownloadField.getText());
		
		// close the SWT dialog window
		dispose();
	}
}
